package com.eastfair.auth.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.eastfair.auth.entity.OrganizationRole;
import com.eastfair.auth.enumeration.OrganizationOrgTypeEnum;
import com.eastfair.auth.enumeration.ResourceOrganizationResourceTypeEnum;
import com.eastfair.auth.model.OrganizationGroup;
import com.eastfair.auth.service.*;
import com.eastfair.auth.dto.OrganizationDTO;
import com.eastfair.auth.entity.Organization;
import com.eastfair.auth.entity.ResourceOrganization;
import com.eastfair.auth.vo.ResourceOrganizationVo;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.eastfair.core.base.R.SUCCESS_CODE;

/**
 * <p>
 * 公司组织操作业务实现类
 *
 * </p>
 *
 * @author ligang
 * @date 2021-07-16
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class CompanyOrganizationServiceImpl implements CompanyOrganizationService {
    @Autowired
    ResourceOrganizationService resourceOrganizationService;

    @Autowired
    UserOrganizationService userOrganizationService;

    @Autowired
    OrganizationRoleService orgRoleService;

    @Autowired
    OrganizationService organizationService;

    @Override
    public R<Organization> createCompanyClassifyOfProject(Long orgId, Long projectId) {
        OrganizationDTO organizationDTO = new OrganizationDTO();
        organizationDTO.setName("项目下的公司分类");
        organizationDTO.setOrgType(OrganizationOrgTypeEnum.P_COMPANY_CLASSIFY);
        organizationDTO.setParentId(orgId);
        organizationDTO.setProjectId(projectId);
        return organizationService.createOrg(organizationDTO);
    }

    @Override
    public R<Organization> createCompanyClassify(Long orgId, Long projectId) {
        OrganizationDTO organizationDTO = new OrganizationDTO();
        organizationDTO.setName("公司组");
        organizationDTO.setOrgType(OrganizationOrgTypeEnum.COMPANY_CLASSIFY);
        organizationDTO.setParentId(orgId);
        organizationDTO.setProjectId(projectId);
        return organizationService.createOrg(organizationDTO);
    }

    @Override
//    @ShardingTransactionType(TransactionType.BASE)
//    @GlobalTransactional(name = "auth", rollbackFor = Exception.class)
//    @Transactional
    public R<Organization> addCompany(OrganizationDTO organizationDTO) {
        String xid = RootContext.getXID();
        log.info("addCompany 事务id is {}", xid);
        //查询公司组节点
        Organization organizationClassify = organizationService.queryOrgOfType(organizationDTO.getProjectId(), OrganizationOrgTypeEnum.COMPANY_CLASSIFY);
        if (organizationClassify != null) {
            //检验资源是否存在
            Organization companyOrganization = organizationService.verifyResourceExistOfOrg(organizationDTO);
            if (companyOrganization != null) {
                //存在则直接返回
                return R.success(companyOrganization);
            }
            //创建项目下的公司信息
            organizationDTO.setParentId(organizationClassify.getId());
            organizationDTO.setOrgType(OrganizationOrgTypeEnum.COMPANY);
            R<Organization> r = organizationService.createOrg(organizationDTO);
            Organization organization = r.getData();
            //公司加入到项目下的公司分类里的指定节点里
            organizationService.addResourceOfOrgIds(organizationDTO.getResourceId(), organizationDTO.getOrgIds(), ResourceOrganizationResourceTypeEnum.COMPANY);
            //加入到项目下的公司分类里
//            addCompanyOfProjectClassify(organization.getProjectId(), organizationDTO.getResourceId(), organizationDTO.getName());
            //创建公司员工
//            OrganizationDTO userOrganizationDTO = new OrganizationDTO();
//            userOrganizationDTO.setOrgType(OrganizationOrgTypeEnum.STAFF);
//            userOrganizationDTO.setName("员工");
//            userOrganizationDTO.setParentId(organization.getId());
//            userOrganizationDTO.setProjectId(organizationDTO.getProjectId());
//            organizationService.createOrg(userOrganizationDTO);
            return R.success(organization);
        }
        return R.fail("操作失败");
    }

    @Override
    public R<Organization> updCompany(OrganizationDTO organizationDTO) {
        //查询公司组节点
        Organization organizationClassify = organizationService.queryOrgOfType(organizationDTO.getProjectId(), OrganizationOrgTypeEnum.COMPANY);
        if (organizationClassify != null) {
            //查询资源相关的组织
            List<ResourceOrganization> resourceOrganizationList = resourceOrganizationService.findResource(organizationDTO.getResourceId());
            if (resourceOrganizationList != null) {
                List<Long> orgIds = resourceOrganizationList.stream().map(ResourceOrganization::getOrganizationId).collect(Collectors.toList());
                List<Organization> organizationList = organizationService.listOfOrganization(null, orgIds);
                if (organizationList != null && !organizationList.isEmpty()) {
                    for (Organization organization : organizationList) {
                        if (organization.getOrgType().getCode().equals(OrganizationOrgTypeEnum.COMPANY.getCode())) {
                            //修改节点名字
                            organization.setName(organizationDTO.getName());
                            organizationService.updateByIdOfShard(organization);
                            //在指定组织里删除资源
                            organizationClassify = organizationService.queryOrgOfType(organizationDTO.getProjectId(), OrganizationOrgTypeEnum.P_COMPANY_CLASSIFY);
                            organizationService.delResource(organizationDTO.getResourceId(), organizationClassify.getId());
                            //公司加入到项目下的公司分类里的指定节点里
                            organizationService.addResourceOfOrgIds(organizationDTO.getResourceId(), organizationDTO.getOrgIds(), ResourceOrganizationResourceTypeEnum.COMPANY);
                            return R.success(organization);
                        }
                    }
                }
            }
        }
        return R.fail("操作失败");
    }

    @Override
    public Organization findCompany(Long resourceId) {
        ResourceOrganization resourceOrganization = new ResourceOrganization();
        resourceOrganization.setResourceId(resourceId);
        List<ResourceOrganization> resourceOrganizationList = resourceOrganizationService.queryResources(resourceOrganization, null, null);
        if (resourceOrganizationList != null && !resourceOrganizationList.isEmpty()) {
            List<Long> orgIds = resourceOrganizationList.stream().map(ResourceOrganization::getOrganizationId).collect(Collectors.toList());
            List<Organization> organizationList = organizationService.listOfOrganization(null, orgIds);
            if (resourceOrganizationList != null && !resourceOrganizationList.isEmpty()) {
                for (Organization organization : organizationList) {
                    if (OrganizationOrgTypeEnum.COMPANY.getCode().equals(organization.getOrgType().getCode())) {
                        return organization;
                    }
                }
            }
        }
        return null;
    }

    @Override
    public R<Organization> addCompanyOfProjectClassify(Long projectId, Long companyId, String resourceName) {
        //查询项目下的公司分类的节点
        Organization organization = organizationService.queryOrgOfType(projectId, OrganizationOrgTypeEnum.P_COMPANY_CLASSIFY);
        if (organization != null) {
            OrganizationDTO organizationDTO = new OrganizationDTO();
            //公司分类的父节点id
            organizationDTO.setParentId(organization.getId());
            organizationDTO.setOrgType(OrganizationOrgTypeEnum.OTHER);
            organizationDTO.setProjectId(projectId);
            organizationDTO.setResourceId(companyId);
            //节点名称
            if (StringUtils.isNotBlank(resourceName)) {
                organizationDTO.setName(resourceName);
            }
            //添加公司到项目下的公司分类
            return organizationService.createOrg(organizationDTO);
        }
        return R.fail("操作失败");
    }


    @Override
    public R addRoleOfResource(Long orgId) {
        //查询节点上的资源
        List<ResourceOrganizationVo> resourceOrganizationVoList = resourceOrganizationService.queryResource(Arrays.asList(orgId));
        //查询节点上的角色
        List<OrganizationRole> orgRoleList = orgRoleService.findOfOrg(Arrays.asList(orgId));
        if (resourceOrganizationVoList != null && !resourceOrganizationVoList.isEmpty() && orgRoleList != null && !orgRoleList.isEmpty()) {
            Long resourceId = resourceOrganizationVoList.get(0).getResourceId();
            //查询组织下的角色id
            List<Long> roleIds = orgRoleList.stream().map(OrganizationRole::getRoleId).collect(Collectors.toList());
            //查找资源所在的公司节点信息
            Organization organization = findCompany(resourceId);
            if (organization != null) {
                organizationService.addOrgRole(organization.getId(), roleIds, true);
            }
        }
        return R.success();
    }

    @Override
    public R removeRoleOfResource(Long orgId) {
        //查询节点上的资源
        List<ResourceOrganizationVo> resourceOrganizationVoList = resourceOrganizationService.queryResource(Arrays.asList(orgId));
        //查询节点上的角色
        List<OrganizationRole> orgRoleList = orgRoleService.findOfOrg(Arrays.asList(orgId));
        if (resourceOrganizationVoList != null && !resourceOrganizationVoList.isEmpty() && orgRoleList != null && !orgRoleList.isEmpty()) {
            Long resourceId = resourceOrganizationVoList.get(0).getResourceId();
            //查询组织下的角色id
            List<Long> roleIds = orgRoleList.stream().map(OrganizationRole::getRoleId).collect(Collectors.toList());
            //查找资源所在的公司节点信息
            Organization organization = findCompany(resourceId);
            if (organization != null) {
                //剔除节点关联的角色
                organizationService.removeOrgRole(organization.getId(), roleIds, true);
            }
        }
        return R.success();
    }

    @Override
    public R breakSysAdminUseridOfCompany(Long resourceId) {
        //公司组织所在的节点
        Organization organization = findCompany(resourceId);
        if (organization != null) {
            //节点剔除用户
            userOrganizationService.delOfOrgIds(Arrays.asList(organization.getId()));
        }
        return R.success();
    }

    @Override
    public R addSysAdminUseridOfCompany(Long resourceId, Long userId) {
        //先剔除节点超级管理员
        breakSysAdminUseridOfCompany(resourceId);
        //公司组织所在的节点
        Organization organization = findCompany(resourceId);
        if (organization != null) {
            //节点添加用户
            userOrganizationService.addUserOfOrg(organization.getId(), Arrays.asList(userId), organization.getProjectId());
        }
        return R.success();
    }


    @Override
    public R removeUseridOfCompany(Long resourceId, List<Long> removeUserIds) {
        //关联节点id集合
        List<Long> orgIds = new ArrayList<>();
        //公司组织所在的节点
        Organization organization = findCompany(resourceId);
        if (organization != null) {
            orgIds.add(organization.getId());
            //查询节点下的所有子节点
            List<Organization> childOrganizationList = organizationService.queryAllOfCode(organization.getCode());
            if (childOrganizationList != null && !childOrganizationList.isEmpty()) {
                orgIds.addAll(childOrganizationList.stream().map(Organization::getId).collect(Collectors.toList()));
            }
            //批量节点剔除用户
            userOrganizationService.removeUserOfOrg(orgIds, removeUserIds);
        }
        return R.success();
    }

    @Override
    public R addUseridOfCompany(Long resourceId, List<Long> userIds) {
        //查询公司员工节点
        Organization organization = findStaffOrganization(resourceId);
        if (organization != null) {
            return userOrganizationService.addUserOfOrg(organization.getId(), userIds, organization.getProjectId());
        }
        return R.success();
    }

    @Override
    public R removeUseridOfExhibition(Long resourceId, List<Long> removeUserIds) {
        //查询公司员工节点
        Organization organization = findStaffOrganization(resourceId);
        //查询展商员工组
        List<Organization> organizationList = organizationService.queryOrgNameOfParent(organization.getCode(), OrganizationGroup.EXHIBITION_STAFF);
        if (organizationList == null || organizationList.isEmpty()) {
            Organization exhibitionUser = organizationList.get(0);
            //关联节点id集合
            List<Long> orgIds = new ArrayList<>();
            orgIds.add(exhibitionUser.getId());
            //查询节点下的所有子节点
            List<Organization> childOrganizationList = organizationService.queryAllOfCode(exhibitionUser.getCode());
            if (childOrganizationList != null && !childOrganizationList.isEmpty()) {
                orgIds.addAll(childOrganizationList.stream().map(Organization::getId).collect(Collectors.toList()));
            }
            //批量节点剔除用户
            userOrganizationService.removeUserOfOrg(orgIds, removeUserIds);
        }
        return R.success();
    }

    @Override
    public R addUseridOfExhibition(Long resourceId, List<Long> userIds) {
        //展商员工组
        Organization exhibitionUser = null;
        //查询公司员工节点
        Organization organization = findStaffOrganization(resourceId);
        //查询展商组是否存在，不存在则添加组
        List<Organization> organizationList = organizationService.queryOrgNameOfParent(organization.getCode(), OrganizationGroup.EXHIBITION_STAFF);
        if (organizationList == null || organizationList.isEmpty()) {
            //不存在则添加组
            OrganizationDTO organizationDTO = new OrganizationDTO();
            organizationDTO.setParentId(organization.getId());
            //节点类型，其他
            organizationDTO.setOrgType(OrganizationOrgTypeEnum.OTHER);
            organizationDTO.setName(OrganizationGroup.EXHIBITION_STAFF);
            organizationDTO.setProjectId(organization.getProjectId());
            R<Organization> organizationR = organizationService.createOrg(organizationDTO);
            if (organizationR.getCode() == SUCCESS_CODE) {
                exhibitionUser = organizationR.getData();
            }
        } else {
            exhibitionUser = organizationList.get(0);
        }
        //添加展商员工
        return userOrganizationService.addUserOfOrg(exhibitionUser.getId(), userIds, organization.getProjectId());
    }

    @Override
    public Organization findStaffOrganization(Long resourceId) {
        //公司组织所在的节点
        Organization organization = findCompany(resourceId);
        if (organization != null) {
            List<Organization> organizationList = organizationService.queryOrgTypeOfParent(organization.getCode(), OrganizationOrgTypeEnum.STAFF);
            if (organizationList != null && !organizationList.isEmpty()) {
                //只取第一个，员工类型的节点只能有一个
                Organization organization1 = organizationList.get(0);
                return organization1;
            }
        }
        return null;
    }


}
